home *** CD-ROM | disk | FTP | other *** search
/ Aminet 3 / Aminet 3 - July 1994.iso / Aminet / util / misc / aterminfo.lha / read_entry.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-12-12  |  4.3 KB  |  191 lines

  1.  
  2. /* This work is copyrighted. See COPYRIGHT.OLD & COPYRIGHT.NEW for   *
  3. *  details. If they are missing then this copy is in violation of    *
  4. *  the copyright conditions.                                        */
  5.  
  6. /*
  7.  *    read_entry.c -- Routine for reading in a compiled terminfo file
  8.  *
  9.  */
  10.  
  11. #include <stdio.h>
  12. #include <stdlib.h>
  13. #ifndef AMIGA
  14. #include <unistd.h>
  15. #endif
  16. #include <fcntl.h>
  17. #include <sys/types.h>
  18. #include <sys/stat.h>
  19. #include "term.h"
  20. #include "object.h"
  21.  
  22. extern int must_swap();
  23.  
  24. TERMINAL *cur_term;
  25.  
  26. #define OFFSET_BUFSIZE    100
  27.  
  28. #define min(a, b)    ((a) > (b)  ?  (b)  :  (a))
  29.  
  30. /*
  31.  *    int
  32.  *    read_entry(filename, ptr)
  33.  *
  34.  *    Read the compiled terminfo entry in the given file into the
  35.  *    structure pointed to by ptr, allocating space for the string
  36.  *    table and placing its address in ptr->str_table.
  37.  *
  38.  */
  39.  
  40. #define swap(x)        (((x >> 8) & 0377) + 256 * (x & 0377))
  41.  
  42. static char    TermNames[128];    /* Buffer for terminal names for first term */
  43. static char    StringTable[1024];    /* String table for first terminal  */
  44.  
  45. int read_entry(char *filename, struct term *ptr)
  46. {
  47. int        fd;
  48. int        numread;
  49. int        num_strings;
  50. int        cur_string;
  51. int        i;
  52. struct header    header;
  53. unsigned char    bytebuf[2];
  54. char        ch;
  55. union {
  56.     short            number;
  57.     unsigned char    byte[2];
  58. } offset_buf[OFFSET_BUFSIZE];
  59.  
  60.     fd = open(filename, 0);
  61.  
  62.     if (fd < 0) {
  63.         fprintf(stderr, "couldn't open file %s.\n", filename);
  64.         exit(1);
  65.     }
  66.  
  67.     read(fd, &header, sizeof(header));
  68.  
  69.     if (must_swap()) {
  70.             header.magic = swap(header.magic);
  71.             header.name_size = swap(header.name_size);
  72.             header.bool_count = swap(header.bool_count);
  73.             header.num_count = swap(header.num_count);
  74.             header.str_count = swap(header.str_count);
  75.             header.str_size = swap(header.str_size);
  76.     }
  77.  
  78.     if (header.magic != MAGIC)
  79.     {
  80.             close(fd);
  81.             return(-1);
  82.     }
  83.  
  84.     read(fd, TermNames, min(127, header.name_size));
  85.     TermNames[127] = '\0';
  86.     ptr->term_names = TermNames;
  87.     if (header.name_size > 127)
  88.             lseek(fd, (long) (header.name_size - 127), 1);
  89.  
  90.     read(fd, ptr->Booleans, min(BOOLCOUNT, header.bool_count));
  91.     if (header.bool_count > BOOLCOUNT)
  92.             lseek(fd, (long) (header.bool_count - BOOLCOUNT), 1);
  93.     else
  94.             for (i=header.bool_count; i < BOOLCOUNT; i++)
  95.             ptr->Booleans[i] = 0;
  96.  
  97.     if ((header.name_size + header.bool_count) % 2 != 0)
  98.             read(fd, &ch, 1);
  99.  
  100.     if (!must_swap()) {
  101.             read(fd, ptr->Numbers, min(NUMCOUNT * 2, header.num_count * 2));
  102.     } else {
  103.             for (i=0; i < min(header.num_count, NUMCOUNT); i++) {
  104.             read(fd, bytebuf, 2);
  105.         if (bytebuf[0] == 0xff  &&  bytebuf[1] == 0xff)
  106.                 ptr->Numbers[i] = -1;
  107.         else
  108.                 ptr->Numbers[i] = bytebuf[0] + 256 * bytebuf[1];
  109.             }
  110.     }
  111.  
  112.     if (header.num_count > NUMCOUNT)
  113.             lseek(fd, (long) (2 * (header.num_count - NUMCOUNT)), 1);
  114.     else
  115.             for (i=header.num_count; i < NUMCOUNT; i++)
  116.             ptr->Numbers[i] = -1;
  117.  
  118.     if (cur_term) { /* cur_term is non-zero only if we've been called */
  119.             ptr->str_table = malloc(header.str_size);
  120.             if (ptr->str_table == NULL) {
  121.             close(fd);
  122.             return (-1);
  123.             }
  124.     } else
  125.             ptr->str_table = StringTable;
  126.  
  127.     num_strings = min(STRCOUNT, header.str_count);
  128.     cur_string = 0;
  129.  
  130.     while (num_strings > 0) {
  131.             numread = read(fd, offset_buf, 2*min(num_strings, OFFSET_BUFSIZE));
  132.             if (numread <= 0) {
  133.             close(fd);
  134.             return(-1);
  135.             }
  136.  
  137.             if (must_swap()) {
  138.             for (i = 0; i < numread / 2; i++) {
  139.                     ptr->Strings[i + cur_string] =
  140.                 (offset_buf[i].byte[0] == 0377
  141.                 &&  offset_buf[i].byte[1] == 0377) ? 0
  142.             : ((offset_buf[i].byte[0] + 256*offset_buf[i].byte[1])
  143.                                   + ptr->str_table);
  144.             }
  145.             } else {
  146.             for (i = 0; i < numread / 2; i++) {
  147.                     ptr->Strings[i + cur_string] =
  148.                 (offset_buf[i].number == -1) ?  0
  149.                 : offset_buf[i].number + ptr->str_table;
  150.             }
  151.             }
  152.  
  153.             cur_string += numread / 2;
  154.             num_strings -= numread / 2;
  155.     }
  156.  
  157.     if (header.str_count > STRCOUNT)
  158.             lseek(fd, (long) (2 * (header.str_count - STRCOUNT)), 1);
  159.     else
  160.             for (i=header.str_count; i < STRCOUNT; i++)
  161.             ptr->Strings[i] = 0;
  162.  
  163.     numread = read(fd, ptr->str_table, header.str_size);
  164.     close(fd);
  165.     if (numread != header.str_size)
  166.             return(-1);
  167.  
  168.     return(0);
  169. }
  170.  
  171.  
  172. /*
  173.  *    int
  174.  *    must_swap()
  175.  *
  176.  *    Test whether this machine will need byte-swapping
  177.  *
  178.  */
  179.  
  180. int
  181. must_swap()
  182. {
  183. union {
  184.     short num;
  185.     unsigned char  byte[2];
  186. }test;
  187.  
  188.     test.num = 1;
  189.     return(test.byte[1]);
  190. }
  191.